/**
 * @description 性能优化工具
 * @author 张一依有把越女剑
 * @date 2025-04-16
 */

// 防抖函数
export function debounce(func, wait, immediate = false) {
	let timeout
	return function executedFunction(...args) {
		const later = () => {
			timeout = null
			if (!immediate) func.apply(this, args)
		}
		const callNow = immediate && !timeout
		clearTimeout(timeout)
		timeout = setTimeout(later, wait)
		if (callNow) func.apply(this, args)
	}
}

// 节流函数
export function throttle(func, limit) {
	let inThrottle
	return function(...args) {
		if (!inThrottle) {
			func.apply(this, args)
			inThrottle = true
			setTimeout(() => inThrottle = false, limit)
		}
	}
}

// 缓存管理
class CacheManager {
	constructor() {
		this.cache = new Map()
		this.maxSize = 50 // 最大缓存数量
		this.ttl = 30 * 60 * 1000 // 30分钟过期
	}
	
	set(key, value, customTTL = null) {
		// 如果缓存已满，删除最旧的项
		if (this.cache.size >= this.maxSize) {
			const firstKey = this.cache.keys().next().value
			this.cache.delete(firstKey)
		}
		
		const expireTime = Date.now() + (customTTL || this.ttl)
		this.cache.set(key, {
			value,
			expireTime
		})
	}
	
	get(key) {
		const item = this.cache.get(key)
		if (!item) return null
		
		// 检查是否过期
		if (Date.now() > item.expireTime) {
			this.cache.delete(key)
			return null
		}
		
		return item.value
	}
	
	clear() {
		this.cache.clear()
	}
	
	// 清理过期缓存
	cleanup() {
		const now = Date.now()
		for (const [key, item] of this.cache.entries()) {
			if (now > item.expireTime) {
				this.cache.delete(key)
			}
		}
	}
}

export const cacheManager = new CacheManager()

// 图片预加载（适配小程序环境）
export function preloadImages(imageUrls) {
	// 在小程序环境中，图片预加载通过uni.preloadPage或其他方式实现
	if (typeof uni !== 'undefined') {
		// 小程序环境下的图片预加载
		return Promise.all(
			imageUrls.map(url => {
				return new Promise((resolve) => {
					// 在小程序中，可以通过创建image组件来预加载
					resolve(url)
				})
			})
		)
	}

	// 浏览器环境下的图片预加载
	if (typeof Image !== 'undefined') {
		return Promise.all(
			imageUrls.map(url => {
				return new Promise((resolve, reject) => {
					const img = new Image()
					img.onload = () => resolve(url)
					img.onerror = () => reject(new Error(`Failed to load image: ${url}`))
					img.src = url
				})
			})
		)
	}

	// 其他环境直接返回
	return Promise.resolve(imageUrls)
}

// 懒加载实现（适配小程序环境）
export function createLazyLoader(selector = '.lazy-load') {
	// 在小程序环境中，懒加载通过scroll-view等组件实现
	if (typeof uni !== 'undefined') {
		// 小程序环境下的懒加载实现
		console.log('Lazy loading in miniprogram environment')
		return {
			observe: () => {},
			unobserve: () => {},
			disconnect: () => {}
		}
	}

	// 浏览器环境下的懒加载
	if (typeof IntersectionObserver !== 'undefined' && typeof document !== 'undefined') {
		const observer = new IntersectionObserver((entries) => {
			entries.forEach(entry => {
				if (entry.isIntersecting) {
					const img = entry.target
					const src = img.dataset.src
					if (src) {
						img.src = src
						img.classList.remove('lazy-load')
						observer.unobserve(img)
					}
				}
			})
		}, {
			rootMargin: '50px'
		})

		document.querySelectorAll(selector).forEach(img => {
			observer.observe(img)
		})

		return observer
	}

	// 其他环境返回空对象
	return {
		observe: () => {},
		unobserve: () => {},
		disconnect: () => {}
	}
}

// 数据分页加载
export function createPagination(data, pageSize = 10) {
	return {
		data,
		pageSize,
		currentPage: 1,
		totalPages: Math.ceil(data.length / pageSize),
		
		getCurrentPageData() {
			const start = (this.currentPage - 1) * this.pageSize
			const end = start + this.pageSize
			return this.data.slice(start, end)
		},
		
		nextPage() {
			if (this.currentPage < this.totalPages) {
				this.currentPage++
				return this.getCurrentPageData()
			}
			return []
		},
		
		prevPage() {
			if (this.currentPage > 1) {
				this.currentPage--
				return this.getCurrentPageData()
			}
			return []
		},
		
		goToPage(page) {
			if (page >= 1 && page <= this.totalPages) {
				this.currentPage = page
				return this.getCurrentPageData()
			}
			return []
		}
	}
}

// 虚拟滚动实现（适配小程序环境）
export class VirtualScroll {
	constructor(options) {
		this.container = options.container
		this.itemHeight = options.itemHeight
		this.data = options.data
		this.renderItem = options.renderItem

		// 检查是否在支持DOM的环境中
		if (this.container && this.container.clientHeight) {
			this.visibleCount = Math.ceil(this.container.clientHeight / this.itemHeight) + 2
		} else {
			this.visibleCount = 10 // 默认值
		}

		this.startIndex = 0
		this.endIndex = this.visibleCount

		if (typeof document !== 'undefined') {
			this.init()
		}
	}
	
	init() {
		if (!this.container || typeof document === 'undefined') {
			return
		}

		this.container.style.position = 'relative'
		this.container.style.overflow = 'auto'

		// 创建滚动容器
		this.scrollContainer = document.createElement('div')
		this.scrollContainer.style.height = `${this.data.length * this.itemHeight}px`
		this.container.appendChild(this.scrollContainer)

		// 创建可见项容器
		this.visibleContainer = document.createElement('div')
		this.visibleContainer.style.position = 'absolute'
		this.visibleContainer.style.top = '0'
		this.visibleContainer.style.width = '100%'
		this.scrollContainer.appendChild(this.visibleContainer)

		this.render()
		this.bindEvents()
	}
	
	render() {
		this.visibleContainer.innerHTML = ''
		
		for (let i = this.startIndex; i < this.endIndex && i < this.data.length; i++) {
			const item = this.renderItem(this.data[i], i)
			item.style.position = 'absolute'
			item.style.top = `${i * this.itemHeight}px`
			item.style.height = `${this.itemHeight}px`
			this.visibleContainer.appendChild(item)
		}
	}
	
	bindEvents() {
		this.container.addEventListener('scroll', throttle(() => {
			const scrollTop = this.container.scrollTop
			const newStartIndex = Math.floor(scrollTop / this.itemHeight)
			const newEndIndex = newStartIndex + this.visibleCount
			
			if (newStartIndex !== this.startIndex || newEndIndex !== this.endIndex) {
				this.startIndex = newStartIndex
				this.endIndex = newEndIndex
				this.render()
			}
		}, 16))
	}
	
	updateData(newData) {
		this.data = newData
		this.scrollContainer.style.height = `${this.data.length * this.itemHeight}px`
		this.render()
	}
}

// 性能监控
export class PerformanceMonitor {
	constructor() {
		this.metrics = {
			pageLoadTime: 0,
			apiResponseTimes: [],
			memoryUsage: 0,
			errorCount: 0
		}
		this.init()
	}
	
	init() {
		// 监控页面加载时间（适配小程序环境）
		if (typeof window !== 'undefined' && window.addEventListener) {
			window.addEventListener('load', () => {
				this.metrics.pageLoadTime = performance.now()
			})

			// 监控错误
			window.addEventListener('error', () => {
				this.metrics.errorCount++
			})
		}

		// 监控内存使用
		if (typeof performance !== 'undefined' && performance.memory) {
			setInterval(() => {
				this.metrics.memoryUsage = performance.memory.usedJSHeapSize
			}, 10000)
		}
	}
	
	// 记录API响应时间
	recordApiTime(startTime, endTime) {
		const responseTime = endTime - startTime
		this.metrics.apiResponseTimes.push(responseTime)
		
		// 只保留最近100次记录
		if (this.metrics.apiResponseTimes.length > 100) {
			this.metrics.apiResponseTimes.shift()
		}
	}
	
	// 获取性能报告
	getReport() {
		const avgApiTime = this.metrics.apiResponseTimes.length > 0 
			? this.metrics.apiResponseTimes.reduce((a, b) => a + b, 0) / this.metrics.apiResponseTimes.length 
			: 0
			
		return {
			pageLoadTime: this.metrics.pageLoadTime,
			averageApiResponseTime: avgApiTime,
			memoryUsage: this.metrics.memoryUsage,
			errorCount: this.metrics.errorCount
		}
	}
}

export const performanceMonitor = new PerformanceMonitor()

// 资源预加载（适配小程序环境）
export function preloadResources(resources) {
	// 在小程序环境中，资源预加载通过其他方式实现
	if (typeof uni !== 'undefined') {
		// 小程序环境下的资源预加载
		console.log('Preloading resources in miniprogram environment', resources)
		return
	}

	// 浏览器环境下的资源预加载
	if (typeof document !== 'undefined') {
		resources.forEach(resource => {
			const link = document.createElement('link')
			link.rel = 'preload'
			link.href = resource.url
			link.as = resource.type || 'fetch'
			document.head.appendChild(link)
		})
	}
}

// 代码分割加载
export async function loadModule(modulePath) {
	const cacheKey = `module_${modulePath}`
	const cached = cacheManager.get(cacheKey)
	
	if (cached) {
		return cached
	}
	
	try {
		const module = await import(modulePath)
		cacheManager.set(cacheKey, module)
		return module
	} catch (error) {
		console.error(`Failed to load module: ${modulePath}`, error)
		throw error
	}
}
